package cn.nkjobsearch.search;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import cn.nkjobsearch.convert.KeywordIndex;
import cn.nkjobsearch.jena.NKJSJena;
import cn.nkjobsearch.mysql.MysqlConn;
import cn.nkjobsearch.publicClass.Print;
import cn.nkjobsearch.publicClass.SearchAndSort;

public class Search {

	public Search() {
		mysql = new MysqlConn();
	}

	public static final int RANK_TITLE = 100;
	public static final int RANK_INTRO = 1;
	
	public static final int RANK_POSITION = 50;		//用户输入的最左边的一个词的位置权重
	public static final int RANK_POSITION_DEC = 5;	//往右依次递减
	
	//{"equal","contain","related","belongToSameKW"};
	public static final double[] RANK_JENA_RELATIONSHIP = new double[] {1, 0.5, 0.5, 0.4};

	public void go(String inputWord) {
		KeywordIndex ki = new KeywordIndex(mysql);
		int[] keywordIdList = ki.getKeywordFromUI(inputWord);
		int[] keywordRp_Rc = new int[keywordIdList.length];//Rank(position)*Rank(count)
		//测试getKeywordFromUI()
//		if(true) {
//			Print.print(keywordIdList);
//			return;
//		}
		if(keywordIdList == null) {
			return;
		}
		int[][] keywordFromJena = getKeywordFromJena(keywordIdList);
		//输出从jena扩展来的词汇id等
		for(int i=0; i<keywordFromJena.length; i++) {
			System.out.println(i + "\t" 
					+ keywordFromJena[i][0] + "\t" 
					+ keywordFromJena[i][1] + "\t" 
					+ keywordFromJena[i][2] + "\t" );
		}
		ArrayList<int[]> idList1 = new ArrayList<int[]>();
		String sql = "SELECT `jobInfoId`,`isTitle` FROM `keywordindex` "
				+ "WHERE `keywordId`='" + keywordIdList[0]
				+ "' order by `jobInfoId` asc;";
		rs = mysql.executeQuery(sql);
		try {
			int indexOfId = SearchAndSort.normalSearch(ki.keywordIdInt, keywordIdList[0]);
			if(indexOfId == -155) {
				System.out.println(keywordIdList[0]);
			}
			keywordRp_Rc[0] = ki.keywordCount[indexOfId] * RANK_POSITION;
			while (rs.next()) {
				int id = rs.getInt(1);
				int isTitle = rs.getInt(2);
				int rank[] = {id, keywordRp_Rc[0] * (isTitle == 1 ? RANK_TITLE : RANK_INTRO)};
				idList1.add(rank);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		ArrayList<int[]> idList2 = null;
		if (keywordIdList.length > 1) {
			idList2 = new ArrayList<int[]>();
			for (int i = 1; i < keywordIdList.length; i++) {
				sql = "SELECT `jobInfoId`,`isTitle` FROM `keywordindex` "
						+ "WHERE `keywordId`='" + keywordIdList[i]
						+ "' order by `jobInfoId` asc;";
				rs = mysql.executeQuery(sql);
				try {
					int indexOfId = SearchAndSort.normalSearch(ki.keywordIdInt, 
							keywordIdList[i]);
					keywordRp_Rc[i] = ki.keywordCount[indexOfId]
					                                  * (RANK_POSITION - RANK_POSITION_DEC*i);
					while (rs.next()) {
						int id = rs.getInt(1);
						int isTitle = rs.getInt(2);
						int rank[] = {id,keywordRp_Rc[i]*(isTitle == 1 ? RANK_TITLE : RANK_INTRO)};
						idList2.add(rank);
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				mergeList(idList1, idList2);
				idList2.clear();
			}
		}
		/* start the keyword from Jena */
		ArrayList<int[]> idListJena = null;
		if (keywordFromJena.length > 0) {
			idListJena = new ArrayList<int[]>();
			for (int i = 0; i < keywordFromJena.length && i<5; i++) {
				sql = "SELECT `jobInfoId`,`isTitle` FROM `keywordindex` "
						+ "WHERE `keywordId`='" + keywordFromJena[i][0]
						+ "' order by `jobInfoId` asc;";
				rs = mysql.executeQuery(sql);
				int indexOfIdInkeywordIdList = SearchAndSort.normalSearch(keywordIdList, 
						keywordFromJena[i][2]);
				try {
					while (rs.next()) {
						int id = rs.getInt(1);
						int isTitle = rs.getInt(2);
						int rank[] = {
								id,
								(int)(keywordRp_Rc[indexOfIdInkeywordIdList]
										* (isTitle == 1 ? RANK_TITLE : RANK_INTRO) 
										* (RANK_JENA_RELATIONSHIP[keywordFromJena[i][1]]))};
						idListJena.add(rank);
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				mergeList(idList1, idListJena);
				idListJena.clear();
			}
		}
		/* end keyword from jena*/
		int[] id = sort(idList1);
		int[] idAsc = id.clone();
		int[] indexOfId = new int[idAsc.length];
		for(int i=0; i<idAsc.length; i++) {
			indexOfId[i] = i;
		}
		SearchAndSort.QuickSort(idAsc, indexOfId, 0, idAsc.length - 1, true);
//		Print.print(id);
		String [][] res = getResultFromDB(id);
		mysql.close();
		for(int i=0; i<id.length; i++) {
			String [] strTmp = res[SearchAndSort.binarySearch(idAsc, id[i])];
			Print.print(i + ": " + id[i] + "\t" + strTmp[1]);
		}
//		Print.print(res);
	}
	
	private int[][] getKeywordFromJena(int[] keywordIdList) {
		ArrayList<int[]> keywordFromJena = new ArrayList<int[]>();// {id, relationship, fromKW_ID}
		NKJSJena jn = new NKJSJena();
		for(int i=0; i<keywordIdList.length; i++) {
			ArrayList<int[]> rs = jn.findKeyword(keywordIdList[i]);
			for(int j=0; j<rs.size(); j++) {
				keywordFromJena.add(new int[]{rs.get(j)[0], rs.get(j)[1], keywordIdList[i]});
			}
		}
		int[][] list = new int[keywordFromJena.size()][3];
		for(int i=0; i<keywordFromJena.size(); i++) {
			list[i][0] = keywordFromJena.get(i)[0];
			list[i][1] = keywordFromJena.get(i)[1];
			list[i][2] = keywordFromJena.get(i)[2];
		}
		SearchAndSort.QuickSort(list, 1, 3, 0, list.length - 1, true);
		return list;
	}
	
	/**
	 * city为null、其它参数为-1时，在搜索时忽略此相应条件
	 * */
	private ArrayList<int[]> getIdsExceptKeyword(int[] city, int exp, 
			int pubDate, int edu, int salary, int jobNature) {
		String cityStr = null;
		//用来标识以后sql语句中是否已经有条件了，以便确定是否要加 'and'
		boolean anyConditionBefore = false;
		if(city != null) {
			cityStr = "'" + city[0] + "'";
		}
		for(int i=1; i<city.length; i++) {
			cityStr += (",'" + city[i] + "'");
		}
		String sql = "select id from jobinfohandled where ";
		if(cityStr != null) {
			anyConditionBefore = true;
			sql += "city in(" + cityStr + ") ";
		}
		if(exp != -1) {
			if(!anyConditionBefore) {
				sql += "and ";
			} else {
				anyConditionBefore = true;
			}
			sql += "(exp = 99 or exp = " + exp + ") ";
		}
		if(pubDate != -1) {
			Date now = new Date( System.currentTimeMillis() - pubDate*24*3600000);
			SimpleDateFormat formattxt = new SimpleDateFormat("yyyy-MM-dd");
			String pubdateLine = formattxt.format(now);
			if(!anyConditionBefore) {
				sql += "and ";
			} else {
				anyConditionBefore = true;
			}
			sql += ("pubDate >= " + pubdateLine + " ");
		}
		if(edu != -1) {
			if(!anyConditionBefore) {
				sql += "and ";
			} else {
				anyConditionBefore = true;
			}
			sql += "(edu = 9 or edu = " + edu + ") ";
		}
		if(salary != -1) {
			if(!anyConditionBefore) {
				sql += "and ";
			} else {
				anyConditionBefore = true;
			}
			sql += "(salary = 0 or exp >= " + salary + ") ";
		}
		if(jobNature != -1) {
			if(!anyConditionBefore) {
				sql += "and ";
			} else {
				anyConditionBefore = true;
			}
			sql += "(exp = " + jobNature + ") ";
		}
		ResultSet rs = mysql.executeQuery(sql);
		ArrayList<int[]> idAndCity = new ArrayList<int[]>();
		try {
			while(rs.next()) {
				idAndCity.add(new int[]{rs.getInt("id"), rs.getInt("city")});
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return idAndCity;
	}
	
	/**
	 * 从数据中取得数据
	 * */
	private String[][] getResultFromDB(int[] id){
		String idAdd = ("" + id[0]);
		for(int i=1; i<id.length; i++) {
			idAdd += (", " + id[i]);
		}
		String sql = "Select id,title from jobinfoHandled where id in (" + idAdd + ");";
		rs = mysql.executeQuery(sql);
		String [][]idAndTitle = new String[id.length][2];
		try {
			for(int i=0; rs.next(); i++){
				idAndTitle[i][0] = rs.getString("id");
				idAndTitle[i][1] = rs.getString("title");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
//		System.out.println(sql);
		return idAndTitle;
	}
	
	/**
	 * @param ArrayList
	 *            <int[]> idList 对idList按照int[1]的值排序
	 */
	private int[] sort(ArrayList<int[]> idList) {
		int listSize = idList.size();
		int[] id = new int[listSize];
		int[] rank = new int[listSize];
		for(int i=0; i<listSize; i++) {
			id[i] = idList.get(i)[0];
		}
		for(int i=0; i<listSize; i++) {
			rank[i] = idList.get(i)[1];
		}
		SearchAndSort.QuickSort(rank, id, 0, listSize-1, false);
		//输出所有的结果集中id的得分		
//		for(int i=0; i<listSize; i++) {
//			System.out.println(id[i] + "\t" + rank[i]);
//		}
		return id;
	}

	/**
	 * 求两个ArrayList的并集，并且保存在第一个参数list1里面
	 */
	private void mergeList(ArrayList<int[]> list1, ArrayList<int[]> list2) {
		int[] ia = new int[list1.size()];
		for (int i = 0; i < list1.size(); i++) {
			ia[i] = list1.get(i)[0];
		}

		for (int i = 0; i < list2.size(); i++) {
			int indexOfIdInList1 = SearchAndSort.normalSearch(ia,
					list2.get(i)[0]);
			if (indexOfIdInList1 != -1) {// find the id in List1
				list1.get(indexOfIdInList1)[1] += list2.get(i)[1];
			} else { // not found, then add it to List1
				list1.add(list2.get(i));
			}
		}
	}
	
	/**
	 * 求两个ArrayList的交集，并且保存在第一个参数list1里面
	 */
	public void mergeListIntersection(ArrayList<int[]> list1, ArrayList<Integer> list2) {	
		int[] ia = new int[list2.size()];
		for (int i = 0; i < list2.size(); i++) {
			ia[i] = list2.get(i);
		}
		for(int i = 0; i<list1.size();) {
			int findIndex = SearchAndSort.binarySearch(ia, list1.get(i)[0]) ;
			//cn.nkjobsearch.publicClass.Print.print(findIndex);
			if(findIndex > -1) {	//found
				i++;
			} else {	//not found
				list1.remove(i);
			}
		}
	}

	private MysqlConn mysql = null;
	private ResultSet rs = null;
}
